﻿namespace Algo.Sort
{
    using System.Collections.Generic;

    internal sealed class BubbleSortStrategy : ISortStrategy
    {
        public IEnumerable<T> Sort<T>(IEnumerable<T> items, IComparer<T> comparer, IAlgoExtensions extensions)
        {
            var iterationsCount = 0;
            var list = SortUtilities.CopyToList(items);
            if (list.Count <= 1)
            {
                return list;
            }

            var count = list.Count - 1;
            try
            {
                for (var i = 0; i < count; i++)
                {
                    for (var j = 0; j < count - i; j++)
                    {
                        var nextPosition = j + 1;
                        if (SortUtilities.IsGreaterThen(comparer, list[j], list[nextPosition]))
                        {
                            SortUtilities.Swap(list, j, nextPosition);
                            iterationsCount++;
                        }
                    }
                }
            }
            finally
            {
                IMetricsExtension metricsBehaviour;
                if (extensions.TryGet(out metricsBehaviour))
                {
                    metricsBehaviour.RegisterIterations(iterationsCount);
                }
            }

            return list;
        }
    }
}
